package com.doge.walknovel.core.account

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.doge.walknovel.App
import com.doge.walknovel.api.*
import com.doge.walknovel.api.model.UserInfo
import com.doge.walknovel.utils.*

class AppUserViewModel : ViewModel() {
    private val folder = "user"
    private val key = "data"
    val user = MutableLiveData<UserInfo?>()

    fun self(): UserInfo {
        // any thread
        val cache = user.value
        if (cache != null) return cache
        val diskCache = spReadString(key, null, folder)
        log("appUser self diskCache $diskCache")
        if (diskCache?.isNotEmpty() == true) {
            fromJson(diskCache, UserInfo::class.java)?.let {
                runOnUI { user.value = (it) }
                return it
            }
        }
        val none = UserInfo.EMPTY
        runOnUI { user.value = none }
        return none
    }

    fun updateSelf(data: UserInfo?) {
        require(isMainThread())
        user.value = data ?: UserInfo.EMPTY
        log("appUser self updateSelf $data")
        runOnIO { spWrite(key, toJson(data), folder) }
    }

    fun requestSelfInfo(callback:(UserInfo)->Unit = {}) = runOnIO {
        log("appUser self requestSelfInfo ${AccountHelper.token}")
        if (AccountHelper.token.isEmpty()) return@runOnIO
        api.userInfo()
            .map(ApiResultMapTransformer())
            .observeOnMain()
            .subscribe(object : ObserverAdapter<UserInfo>() {
                override fun onNext(t: UserInfo) {
                    updateSelf(t)
                    callback(t)
                }

                override fun onError(e: Throwable) {
                    // silently
                }
            })
    }

    companion object {
        fun get(): AppUserViewModel {
            return (appContext as App).getAppViewModelProvider().get(AppUserViewModel::class.java)
        }
    }
}